//===============================================================================
// Microsoft patterns & practices Enterprise Library Contribution
// Resource Application Block
//===============================================================================

using System;
using System.Globalization;
using System.IO;
using System.Configuration;
using System.Reflection;
using EntLibContrib.Resource;
using EntLibContrib.Resource.Managers;

namespace EntLibContrib.Resource.Providers
{
	/// <summary>
	/// Abstract File based Resource Provider.
	/// </summary>
	/// <remarks>
	/// This provider loads a resource file and generates a <see cref="ExtendedComponentResourceManager" /> populated
	/// with resources from the file.
	/// </remarks>
	public abstract class FileResourceProvider : ResourceProvider
	{
		#region Fields
		private string resourcePathName;
		#endregion

		#region Construction
		/// <summary>
		/// Initializes a new default instance of the <see cref="FileResourceProvider"/> class.
		/// </summary>
		/// <param name="resourcePathName">Name of the resource path.</param>
		/// <param name="resourceBaseName">Name of the resource base.</param>
		protected FileResourceProvider(string resourcePathName, string resourceBaseName)
			: base(resourceBaseName)
		{
			ValidateAndStoreParameters(resourcePathName);
		}
		#endregion

		#region Public Methods
		/// <summary>
		/// Create a Resource Manager to manage the resource for a file based resource provider
		/// </summary>
		/// <returns>A <see cref="ExtendedComponentResourceManager" /> instance</returns>
		/// <remarks>
		/// <para>This method makes a <see cref="ExtendedComponentResourceManager"/> instance publicly available
		/// based on the path name and base name retrieved during Initialisation</para>
		/// </remarks>
		public override ExtendedComponentResourceManager CreateResourceManager()
		{  
			// Check for first time use of resource manager
			if (ResourceManager == null)
			{
				// Generate a Resource Manager
				ResourceManager = CreateFileResourceManager(resourcePathName, ResourceBaseName);
				ResourceManager.IgnoreCase = true;
			}
			return ResourceManager;
		}

		/// <summary>
		/// Creates the file resource manager.
		/// </summary>
		/// <returns>instance of the file resource manager type</returns>
		protected abstract ExtendedComponentResourceManager CreateFileResourceManager(string resourcePathName, string resourceBaseName);

		/// <summary>
		/// Gets the file resource extension.
		/// </summary>
		/// <returns>extension without the separator</returns>
		protected abstract string FindFileResourceExtension();
		#endregion

		#region Private Methods
		/// <summary>
		/// Validates the and store parameters.
		/// </summary>
		/// <param name="resourcePathName">Name of the resource path.</param>
		private void ValidateAndStoreParameters (string resourcePathName)
		{
			// check for a null or empty path name
			if ( string.IsNullOrEmpty(resourcePathName) )
				throw new ArgumentException(InternalResources.ExceptionFileResourcePathNameNullOrEmpty);

			// check that the path name represents a valid path
			DirectoryInfo directoryInfo = new DirectoryInfo(resourcePathName);
			if ( !directoryInfo.Exists )
				throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, InternalResources.ExceptionFileResourcePathNameInvalid, resourcePathName), resourcePathName);

			// store the path name
			this.resourcePathName = resourcePathName;

			// Check for a valid base name by looking for the neutral or invariant resource file
			FileInfo fileInfo = new FileInfo(ResourceFileName.Build(resourcePathName, ResourceBaseName, null, FindFileResourceExtension()));
			if ( !fileInfo.Exists )
				throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, InternalResources.ExceptionFileResourceBaseNameInvalid, fileInfo.FullName), ResourceBaseName);
		}
		#endregion
	}
}
